
//  WebScoket.swift
//  Exchange
//
//  Created by 孟祥群 on 2018/5/9.
//  Copyright © 2018年 common. All rights reserved.
//

import UIKit
import Starscream
import Gzip
@objc protocol ExchangeScoketDelegate {
    /**websocket 连接成功*/
    @objc optional func websocketDidConnect()
    /**websocket 连接失败*/
    @objc optional  func websocketDidDisconnect(error: NSError?)
    /**websocket 接收文字信息*/
    @objc optional func websocketDidReceiveMessage(text: String)
    /**websocket 接收二进制信息*/
    @objc optional  func  websocketDidReceiveData(data: NSData)
    
    func exchangeScoketDidConnect()
}
class ExchangeScoket: NSObject, WebSocketDelegate {
    var scoket:WebSocket?
    var delegate:ExchangeScoketDelegate?
    var webInfor:ExchangeWebInfo?
    var reConnectTime:TimeInterval = 0
    var heartBeat:Timer?
    var model:ExchangeModel?
    init(model:ExchangeModel) {
        super.init()
        self.model = model
        webInfor = ExchangeWebInfoFactory.manger.archiveWebInfor(identifier: .exchangeBase)
    }
    func connectSever()  {
        self.scoket = WebSocket(url: URL(string: (self.webInfor?.requestUrl)!)!)
        self.scoket!.delegate = self
        self.scoket!.connect()
    }
    
    func sendWrite(infor:ExchangeWebInfo,cancelBool:Bool) {
        var dic = (infor as? CYWebInfoProtocol)?.writeData
//        if cancelBool {
//            dic!["channel"] = "del" as AnyObject
//        }else {
//            dic!["channel"] = "add" as AnyObject
//        }
        let jsonString = model?.convertDictionaryToString(dict: dic!)
        let editString = String(format: "%@",jsonString!)
        scoket!.write(string: editString )
    }
    
    func sendBrandData(data:Data) {
        scoket!.write(data: data)
    }
    @objc func sendWriteHeart() {
        if scoket?.isConnected != nil {
            if (scoket?.isConnected)!  {
                let jsonString = model?.convertDictionaryToString(dict: ["cmd":"ping" as AnyObject])
                let editString = String(format: "%@",jsonString!)
                scoket!.write(string: editString)
            }
        }
    }
    //MARK:- 关闭消息
    func disconnect(){
        scoket!.disconnect()
    }
    
    //MARK: - WebSocketDelegate
    func websocketDidConnect(socket: WebSocketClient) {
        reConnectTime = 0
        self.initHeartBeat()
        if delegate != nil && (delegate?.exchangeScoketDidConnect) != nil {
            self.delegate?.exchangeScoketDidConnect()
        }
    }
    
    func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
        print("fail========")
        scoket = nil
        self.reCounnect()
        if delegate != nil && ((delegate?.websocketDidDisconnect) != nil){
            if error != nil {
                
                self.delegate?.websocketDidDisconnect!(error: error! as NSError)
            }
        }
    }
    
    func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
//        let operation = BlockOperation {
//            self.changeData(text: text)
//        }
//        ExchangeWebScoket.manger.queue.addOperation(operation)
        if delegate != nil && ((delegate?.websocketDidReceiveMessage) != nil){
            self.delegate?.websocketDidReceiveMessage!(text: text)
        }
    }
    
    func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
        print("aaaaa========")
        if delegate != nil && ((delegate?.websocketDidReceiveData) != nil) {
            self.delegate?.websocketDidReceiveData!(data: data as NSData)
        }
    }

    
    public func checkScoketConnected() -> Bool {
        if self.scoket?.isConnected != nil {
            if (self.scoket?.isConnected)! {
                return true
            }
        }
        return false
    }
    
    
    func initHeartBeat() {
        if Thread.isMainThread {
            self.destoryHeartBeat()
            self.heartBeat = Timer.init(timeInterval: 5, target: self, selector: #selector(self.sendWriteHeart), userInfo: nil, repeats: true)
            RunLoop.current.add(self.heartBeat!, forMode: RunLoopMode.commonModes)
        }else {
            
            DispatchQueue.main.async{
                self.destoryHeartBeat()
                self.heartBeat = Timer.init(timeInterval: 5, target: self, selector: #selector(self.sendWriteHeart), userInfo: nil, repeats: true)
                RunLoop.current.add(self.heartBeat!, forMode: RunLoopMode.commonModes)
            }
        }
    }
    
    func reCounnect()  {
        self.SRWebSocketClose()
        if (reConnectTime > 64) {
            //您的网络状况不是很好，请检查网络后重试
            reConnectTime = 0
            return;
        }
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2*reConnectTime, execute: {
            self.scoket = nil
            self.connectSever()
        })
        if reConnectTime == 0 {
            reConnectTime = 2
        }else {
        reConnectTime = reConnectTime*2
        }
    }
    
    func SRWebSocketClose() {
        if (self.scoket != nil) {
            self.scoket?.disconnect()
            self.scoket = nil
            self.destoryHeartBeat()
        }
    }
    
    func destoryHeartBeat() {
        if Thread.isMainThread {
            if self.heartBeat != nil {
                self.heartBeat?.invalidate()
                self.heartBeat = nil
            }
        }else {
        DispatchQueue.main.async {
            if self.heartBeat != nil {
                self.heartBeat?.invalidate()
                self.heartBeat = nil
            }
         }
        }
    }
    
    
}
